/**
 * WebSocket服务工具类
 * 用于处理实时K线数据连接和消息解析
 */

import { getWebSocketConfig } from './config.js'

class WebSocketService {
  constructor() {
    this.ws = null;
    this.isConnected = false;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectInterval = 3000;
    this.heartbeatInterval = null;
    this.heartbeatTimer = 30000; // 30秒心跳
    this.subscribers = new Map(); // 存储订阅者
    // 使用配置文件中的WebSocket URL
    const wsConfig = getWebSocketConfig()
    this.wsUrl = wsConfig.baseUrl;
    this.token = null;
    this.statusListeners = []; // 状态变化监听器
    this.messageListeners = []; // 消息监听器
  }

  /**
   * 连接WebSocket
   * @param {string} accessToken - 访问令牌
   */
  connect(accessToken) {
    // console.log('🔧 WebSocket connect方法被调用，accessToken:', accessToken ? '***' : 'null');
    
    if (this.ws && this.isConnected) {
      // console.log('🔗 WebSocket已连接，返回现有连接');
      return Promise.resolve();
    }

    // 检查token有效性
    if (!accessToken) {
      console.warn('⚠️ 无效token，WebSocket连接失败');
      return Promise.reject(new Error('无效的访问令牌'));
    }

    this.token = accessToken;
    const url = `${this.wsUrl}?token=${accessToken}`;
    // console.log('🔌 准备连接WebSocket:', url.replace(accessToken, '***'));

    return new Promise((resolve, reject) => {
      try {
        // console.log('🔌 创建WebSocket连接:', url.replace(accessToken, '***'));
        this.ws = new WebSocket(url);

        this.ws.onopen = () => {
          // console.log('✅ WebSocket连接成功');
          this.isConnected = true;
          this.reconnectAttempts = 0;
          this.startHeartbeat();
          this.notifyStatusChange(true);
          resolve();
        };

        this.ws.onmessage = (event) => {
          this.handleMessage(event.data);
        };

        this.ws.onclose = (event) => {
          // console.log('🔌 WebSocket连接关闭:', event.code, event.reason);
          this.isConnected = false;
          this.stopHeartbeat();
          this.notifyStatusChange(false);
          
          // 自动重连
          if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnect();
          }
        };

        this.ws.onerror = (error) => {
          console.error('❌ WebSocket连接错误:', error);
          this.isConnected = false;
          this.notifyStatusChange(false);
          reject(new Error('WebSocket连接失败，请检查网络连接和token有效性'));
        };

        // 连接超时处理
        setTimeout(() => {
          if (!this.isConnected) {
            console.error('⏰ WebSocket连接超时');
            if (this.ws) {
              this.ws.close();
            }
            reject(new Error('WebSocket连接超时'));
          }
        }, 10000);

      } catch (error) {
        console.error('❌ WebSocket连接异常:', error);
        reject(error);
      }
    });
  }

  /**
   * 处理接收到的消息
   * @param {string} data - 消息数据
   */
  handleMessage(data) {
    try {
      const message = JSON.parse(data);
      // 如果有监听器，通知所有消息监听器
      if (this.messageListeners.length > 0) {
        this.messageListeners.forEach((listener, index) => {
          try {
            // console.log(`📨 调用监听器 ${index + 1}/${this.messageListeners.length}`);
            listener(message);
          } catch (error) {
            console.error('执行消息监听器失败:', error);
          }
        });
      } 
      
    } catch (error) {
      console.error('解析WebSocket消息失败:', error, data);
    }
  }

  /**
   * 订阅产品数据（仅管理回调，不发送订阅消息）
   * @param {number} productId - 产品ID
   * @param {string} klineType - K线类型
   * @param {function} callback - 回调函数
   * @returns {function} 取消订阅函数
   */
  subscribe(productId, klineType = 'min1', callback) {
    const key = `${productId}-${klineType}`;

    if (!this.subscribers.has(key)) {
      this.subscribers.set(key, []);
    }

    this.subscribers.get(key).push(callback);

    return () => {
      // 返回取消订阅函数
      this.unsubscribe(productId, klineType, callback);
    };
  }

  /**
   * 取消订阅（仅移除回调，不发送取消订阅消息）
   * @param {number} productId - 产品ID
   * @param {string} klineType - K线类型
   * @param {function} callback - 回调函数
   */
  unsubscribe(productId, klineType, callback) {
    const key = `${productId}-${klineType}`;

    if (this.subscribers.has(key)) {
      const callbacks = this.subscribers.get(key);
      const index = callbacks.indexOf(callback);
      if (index > -1) {
        callbacks.splice(index, 1);
      }

      // 如果没有订阅者了，删除该key
      if (callbacks.length === 0) {
        this.subscribers.delete(key);
      }
    }
  }

  /**
   * 开始心跳
   */
  startHeartbeat() {
    this.heartbeatInterval = setInterval(() => {
      if (this.isConnected && this.ws) {
        this.ws.send(JSON.stringify({ type: 'ping' }));
      }
    }, this.heartbeatTimer);
  }

  /**
   * 停止心跳
   */
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }

  /**
   * 重连
   */
  reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      // console.log('达到最大重连次数，停止重连');
      return;
    }

    this.reconnectAttempts++;
    // console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);

    setTimeout(() => {
      if (this.token) {
        this.connect(this.token).catch(error => {
          console.error('重连失败:', error);
        });
      }
    }, this.reconnectInterval);
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.stopHeartbeat();
    this.subscribers.clear();
    
    if (this.ws) {
      this.isConnected = false;
      this.ws.close();
      this.ws = null;
    }
    
    this.notifyStatusChange(false);
  }

  /**
   * 获取连接状态
   */
  getConnectionStatus() {
    return {
      isConnected: this.isConnected,
      reconnectAttempts: this.reconnectAttempts,
      subscribersCount: this.subscribers.size,
      messageListenersCount: this.messageListeners.length
    };
  }

  /**
   * 添加状态变化监听器
   * @param {Function} listener - 监听器函数
   */
  addStatusListener(listener) {
    this.statusListeners.push(listener);
  }

  /**
   * 移除状态变化监听器
   * @param {Function} listener - 监听器函数
   */
  removeStatusListener(listener) {
    const index = this.statusListeners.indexOf(listener);
    if (index > -1) {
      this.statusListeners.splice(index, 1);
    }
  }

  /**
   * 通知状态变化
   * @param {boolean} connected - 连接状态
   */
  notifyStatusChange(connected) {
    this.statusListeners.forEach(listener => {
      try {
        listener(connected);
      } catch (error) {
        console.error('状态监听器执行失败:', error);
      }
    });
  }

  /**
   * 添加消息监听器
   * @param {Function} listener - 监听器函数
   */
  addMessageListener(listener) {
    this.messageListeners.push(listener);
  }

  /**
   * 移除消息监听器
   * @param {Function} listener - 监听器函数
   */
  removeMessageListener(listener) {
    const index = this.messageListeners.indexOf(listener);
    if (index > -1) {
      this.messageListeners.splice(index, 1);
    }
  }

  /**
   * 发送消息
   * @param {object} message - 要发送的消息
   */
  send(message) {
    if (this.isConnected && this.ws) {
      this.ws.send(JSON.stringify(message));
      // console.log('发送WebSocket消息:', message);
    } else {
      // console.warn('WebSocket未连接，无法发送消息:', message);
    }
  }
}

// 创建单例实例
const websocketService = new WebSocketService();

export default websocketService;